package com.kuiniu.threeframe.client.entity;

/**
 * 线程不安全
 */

public class AnalysisJsonData {
    /**
     * 分隔符
     */
    private final String division;
    private int divisionLength;
    /**
     * 数据位长度
     */
    private final int length;
    private int needReadLength = 0;

    private StringBuffer readBuffer = new StringBuffer(1024 * 5);
    private StringBuffer dataBuffer = new StringBuffer(2048);
    private OnDataResult result;


    public AnalysisJsonData(String division, int length, OnDataResult result) {
        this.division = division;
        this.length = length;
        this.result = result;
        divisionLength = division.length();
    }

    public void addString(String str) {
        readBuffer.append(str);
        analysisData();
    }

    private void analysisData() {
        if (readBuffer.length() >= (divisionLength + length) && needReadLength == 0) {
            //长度超过阈值才处理
            int index = Kmp.kmpMatch(readBuffer.toString(), division);
            //kmp算法找到分隔符第一次出现的位置
            if (index == -1) {
                readBuffer.setLength(0);
            } else {
                if ((readBuffer.length() - index - divisionLength) >= length) {
                    int frameLength = Integer.parseInt(readBuffer.substring(index + divisionLength,
                            index + divisionLength + length));
                    readBuffer.delete(0, index + divisionLength + length);
                    if (readBuffer.length() >= frameLength) {
                        dataBuffer.append(readBuffer.substring(0, frameLength));
                        readBuffer.delete(0, frameLength);
                        if (result != null) {
                            result.onResult(dataBuffer.toString());
                        }
                        dataBuffer.setLength(0);
                        //递归遍历完成
                        analysisData();
                    } else {
                        dataBuffer.append(readBuffer.substring(0, readBuffer.length()));
                        readBuffer.setLength(0);
                        needReadLength = frameLength - dataBuffer.length();
                    }
                }
            }
        } else if (needReadLength > 0) {
            if (readBuffer.length() >= needReadLength) {
                dataBuffer.append(readBuffer.substring(0, needReadLength));
                readBuffer.delete(0, needReadLength);
                needReadLength = 0;
                if (result != null) {
                    result.onResult(dataBuffer.toString());
                }
                dataBuffer.setLength(0);
                analysisData();
            }
        }
    }

    public static interface OnDataResult {
        public void onResult(String t);
    }
}
